package com.lmk.utils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.lmk.dsa.struct.graph.DenseGraph;
import com.lmk.dsa.struct.graph.Graph;
import com.lmk.dsa.struct.graph.SparseGraph;

/**
 * 文件工具类
 * @author LaoMake
 * @since 1.0
 */
public class FileUtils {

    /** 默认为无向图 */
    public static boolean isDirected = false;

    /**
     * 将指定路径的文件读取为一个稀疏图
     * @param filePath
     * @return
     */
    public static Graph readGraph(String filePath){
        return readGraph(filePath, true);
    }

    /**
     * 将指定路径的文件读取为一个图
     * @param filePath  文件路径（相对路径）
     * @param isSparse   是否为稀疏图
     * @return
     */
    public static Graph readGraph(String filePath, boolean isSparse){
        Graph graph = null;

        try(InputStream is  = FileUtils.class.getClassLoader().getResourceAsStream(filePath);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        ){
            // 读取第一行
            String str = reader.readLine();
            int[] numbers = readNumbers(str);
            int n = numbers[0];
            int m = numbers[1];

            if(isSparse){
                graph = new SparseGraph(n);
                graph.setDirected(isDirected);
            }else{
                graph = new DenseGraph(n);
                graph.setDirected(isDirected);
            }


            // 读取顶点
            for (int i = 0; i < n; i++) {
                graph.addVertex(reader.readLine());
            }

            // 读取边
            int weight = 1;
            for (int i = 0; i < m; i++) {
                str = reader.readLine();
                if(str != null){
                    weight = 1;
                    numbers = readNumbers(str);
                    if(numbers.length > 2){
                        weight = numbers[2];
                    }

                    graph.addEdge(numbers[0], numbers[1], weight);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return graph;
    }

    /**
     * 将类似：【6 9】 这种以空格分隔的字符串解析成整数数组
     * @param str
     * @return
     */
    private static int[] readNumbers(String str){
        assert str != null : "字符串不能为空";
        assert str.length() >= 3 : "字符串格式错误：" + str;

        String[] strs = str.split(" ");
        int[] numbers = new int[strs.length];
        for (int i = 0; i < strs.length; i++) {
            numbers[i] = Integer.valueOf(strs[i]);
        }

        return numbers;
    }

}
